import { computed, ComputedRef, ref, Ref } from 'vue';
import { defineStore } from 'pinia';
import {
  PlaybackWatchBasicInfo,
  LiveStatus,
  MobileWatchLayout,
  generateDefaultAccountInfo,
  AccountInfo,
} from '@polyv/live-watch-sdk';

import { paramGetter } from '@/hooks/core/use-query-params';
import { appEvents, eventBus } from '@/app/app-events';

import { getWatchCore } from '@/core/watch-sdk';
import { PageErrorData, PageErrorType } from '@/app/layout/page-error/page-error-type';

import { useChannelStore } from './use-channel-store';
import { useAuthStore } from './use-auth-store';
import { useEnrollStore } from './use-enroll-store';
import { useLayoutStore } from './use-layout-store';
import { usePlaybackStore } from './use-playback-store';
import { usePlayerStore } from './use-player-store';
import { useDocStore } from './use-doc-store';
import { useChatStore } from './use-chat-store';
import { useFinanceStore } from './use-finance-store';
import { useConnectMicStore } from './use-connect-mic-store';
import { useSyncStoreForWatchPage } from '@/hooks/core/use-sync-store';
import { useMultiMeetingRedirect } from '@/components/page-watch-common/multi-meeting/hooks/use-multi-meeting-redirect';

import { translate } from '@/assets/lang';
import { isMobile } from '@/assets/utils/browser';
import { useWebviewStore } from './use-webview-store';

export interface WatchAppStoreState {
  /** 当前是否处于回放观看页地址 */
  isPlaybackWatchUrl: Ref<boolean>;
  /** 回放观看页基本信息 */
  playbackWatchBasicInfo: Ref<PlaybackWatchBasicInfo>;
  /** 当前是否为微信小程序 webview 环境 */
  isWxMiniProgram: Ref<boolean>;
  /** 是否为会议模式 */
  meetingMode: ComputedRef<boolean>;
  /** 是否 iframe 模式 */
  iframeMode: Ref<boolean>;
  /** 页面异常数据 */
  pageError: Ref<PageErrorData | undefined>;
  /** 观看页应用初始化完毕 */
  watchAppInited: Ref<boolean>;
  /** 账户信息 */
  accountInfo: Ref<AccountInfo>;

  /**
   * 由于单页面没有路由机制，所以通过标志位来销毁组件
   * @warn shouldShowForceAuth、shouldShowSplash、watchPageInited 三个变量只能有一个为 true
   */

  /** 是否显示强制授权页 - 强制授权页标识位 */
  shouldShowForceAuth: Ref<boolean>;
  /** 是否显示引导页 - 引导页渲染标识位 */
  shouldShowSplash: ComputedRef<boolean>;
  /** 直播观看页是否初始化完毕 - 直播观看页渲染标识位 */
  watchPageInited: Ref<boolean>;

  /** 直播观看页部分功能已初始化 */
  isLiveWatchConnected: Ref<boolean>;

  /** 观看页聊天室 socket 已连接 */
  watchPageChatConnected: Ref<boolean>;
}

export interface WatchAppStoreActions {
  /** 设置页面错误数据 */
  setPageError(param: PageErrorData): void;
  /** 重置 watchCore */
  resetUpWatchCore(): Promise<void>;
  /** 同步 watchAppStore 数据 */
  syncWatchAppStore(): void;
  /** 设置直播观看页 */
  setupLiveWatch(): Promise<void>;
  /** 暂停直播观看页部分功能的初始化 */
  pauseConnectLiveWatch(): void;
  /** 恢复直播观看页部分功能的初始化 */
  recoverConnectLiveWatch(): void;
  /** 连接聊天室 */
  setupWatchCoreConnect(): Promise<void>;
}

export interface WatchAppStore extends WatchAppStoreState, WatchAppStoreActions {}

export const useWatchAppStore = defineStore<'watchApp', WatchAppStore>('watchApp', () => {
  const { syncStoreBeforeWatchPageInited, syncStoreAfterWatchPageInited } =
    useSyncStoreForWatchPage();
  const { checkRedirectSubChannel } = useMultiMeetingRedirect();

  const authStore = useAuthStore();
  const enrollStore = useEnrollStore();

  const layoutStore = useLayoutStore();

  const channelStore = useChannelStore();
  const docStore = useDocStore();
  const playbackStore = usePlaybackStore();
  const playerStore = usePlayerStore();
  const chatStore = useChatStore();
  const connectMicStore = useConnectMicStore();

  const financeStore = useFinanceStore();
  const webviewStore = useWebviewStore();

  /** 当前是否处于回放观看页地址 */
  const isPlaybackWatchUrl = ref(false);

  /** 回放观看页基本信息 */
  const playbackWatchBasicInfo = ref<PlaybackWatchBasicInfo>({});

  /** 当前是否为微信小程序 webview 环境 */
  const isWxMiniProgram = ref(false);

  /** 是否为会议模式 */
  const meetingMode = computed(() => {
    // 移动端横屏下才需要进入会议模式
    if (isMobile && layoutStore.mobileWatchLayout === MobileWatchLayout.Normal) {
      return paramGetter.polyvMeeting() === 'true';
    }

    return false;
  });

  /** 是否 iframe 模式 */
  const iframeMode = ref(paramGetter.hasFrame() === '1');

  /** 页面异常数据 */
  const pageError = ref<PageErrorData>();

  /** 观看页应用初始化完毕 */
  const watchAppInited = ref(false);

  /** 是否显示强制授权页 */
  const shouldShowForceAuth = ref(false);

  /** 是否显示引导页 */
  const shouldShowSplash = computed(() => {
    if (shouldShowForceAuth.value) return false;

    return (
      !authStore.isAuthorized ||
      enrollStore.needEnrollByEnter ||
      financeStore.shouldShowSplashByRiskEvaluation
    );
  });

  /** 直播观看页是否初始化完毕 */
  const watchPageInited = ref(false);

  /** 观看页需要聊天室 socket */
  const watchPageNeedChatSocket = ref(false);

  /** 直播观看页部分功能已初始化 */
  const isLiveWatchConnected = ref(false);

  /** 观看页聊天室 socket 已连接 */
  const watchPageChatConnected = ref(false);

  /** 账户信息 */
  const accountInfo = ref(generateDefaultAccountInfo());

  /** 设置页面异常数据 */
  function setPageError(param: PageErrorData) {
    // 只设置一次
    if (pageError.value) return;

    pageError.value = param;
  }

  /** 重置 watchCore */
  async function resetUpWatchCore(): Promise<void> {
    try {
      const watchCore = getWatchCore();
      await watchCore.setup();
    } catch (error) {
      setPageError({
        type: PageErrorType.UnknownError,
        title: translate('pageError.channel.unknowError'),
        desc: translate('pageError.channel.feedBack'),
      });
      console.error('resetUpWatchCore error', error);
      // 需要抛出主流程阻塞的异常
      throw new Error('页面初始化失败！');
    }
  }

  /** 同步 watchAppStore 数据 */
  function syncWatchAppStore() {
    const watchCore = getWatchCore();

    accountInfo.value = watchCore.getAccountInfo();
    shouldShowForceAuth.value =
      watchCore.weixin.checkForceWxAuth() || watchCore.identity.checkIdentityWxAuth();
    isPlaybackWatchUrl.value = watchCore.isPlaybackWatchByVid();
    playbackWatchBasicInfo.value = watchCore.getPlaybackWatchBasicInfo();
  }

  /** 设置观看页 */
  async function setupLiveWatch(): Promise<void> {
    // 从分会场跳转到主会场并授权成功，则跳回对应的分会场，跳转后阻止观看页渲染
    const checkResult = checkRedirectSubChannel();
    if (checkResult) {
      return;
    }

    // 同步相关 store 的数据
    syncStoreBeforeWatchPageInited();

    // 初始化当前回放对象
    await playbackStore.initCurrentPlaybackTarget();

    // 根据不同场景设置 watchPageInited 标识位
    __setWatchPageInited();

    // 同步相关 store 的数据
    syncStoreAfterWatchPageInited();
  }

  /** 根据不同场景设置 watchPageInited 标识位 */
  function __setWatchPageInited() {
    // 开启风险确认函时，需要暂停部分功能初始化和 Socket 链接
    // 等到观众同意确认后再进行恢复
    if (
      financeStore.riskConfirmEnabled ||
      (paramGetter.watchPageInitStatus() === 'inactive' && !isLiveWatchConnected.value)
    ) {
      pauseConnectLiveWatch();
      watchPageInited.value = true;
      return;
    }

    /**
     * 不需要连麦，不需要连接聊天室
     * @scene 回放观看页地址进入观看页
     * @scene 研讨会处于"内部研讨"时不需要连接聊天室
     * @scene 研讨会处于回放时不需要连接聊天室
     */
    if (
      isPlaybackWatchUrl.value ||
      channelStore.privateSeminarChannel ||
      (channelStore.isSeminarChannel && channelStore.liveStatus === LiveStatus.Playback)
    ) {
      connectMicStore.$patch({ connectMicEnabled: false });
      watchPageInited.value = true;
      return;
    }

    // 正常进入观看页，需要建立 socket 连接
    watchPageNeedChatSocket.value = true;
    isLiveWatchConnected.value = true;
    watchPageInited.value = true;
  }

  // 处理重复连接 socket 的逻辑
  let connecting = false;
  /**
   * 设置观看核心连接 Socket 处理
   */
  async function setupWatchCoreConnect() {
    if (!watchPageNeedChatSocket.value || watchPageChatConnected.value) return;

    const watchCore = getWatchCore();
    if (connecting) {
      return;
    }

    connecting = true;
    await watchCore.connect();

    connecting = false;
    watchPageChatConnected.value = true;
  }

  /**
   * 暂停直播观看页部分功能的初始化
   * */
  async function pauseConnectLiveWatch() {
    isLiveWatchConnected.value = false;
    playerStore.$patch({ playerEnabled: false });
    docStore.$patch({ docEnabled: false });
    chatStore.$patch({ chatMsgListEnabled: false });
    connectMicStore.$patch({ connectMicEnabled: false });
  }

  /**
   * 恢复直播观看页部分功能的初始化
   */
  async function recoverConnectLiveWatch() {
    // 当前如果处于 webview 激活状态，要优先设置状态位
    if (webviewStore.curWebviewPageIsActive) {
      isLiveWatchConnected.value = true;
    }

    if (!watchPageInited.value) return;

    isLiveWatchConnected.value = true;
    playerStore.$patch({ playerEnabled: true });
    docStore.$patch({ docEnabled: true });
    chatStore.$patch({ chatMsgListEnabled: true });

    /**
     * 需要连麦，需要连接聊天室
     */
    if (
      !(
        isPlaybackWatchUrl.value ||
        channelStore.privateSeminarChannel ||
        (channelStore.isSeminarChannel && channelStore.liveStatus === LiveStatus.Playback)
      )
    ) {
      watchPageNeedChatSocket.value = true;
      await setupWatchCoreConnect();
      connectMicStore.$patch({ connectMicEnabled: true });
    }

    eventBus.$emit(appEvents.player.ResetUpPlayer);
    eventBus.$emit(appEvents.doc.ResetUpDoc);
    eventBus.$emit(appEvents.chat.ResetUpChatMsgList);
    eventBus.$emit(appEvents.connectMic.ResetUpConnectMic);
  }

  return {
    isPlaybackWatchUrl,
    playbackWatchBasicInfo,
    isWxMiniProgram,
    meetingMode,
    iframeMode,
    pageError,
    accountInfo,
    watchAppInited,
    shouldShowForceAuth,
    shouldShowSplash,
    watchPageInited,

    setPageError,
    resetUpWatchCore,
    syncWatchAppStore,
    setupLiveWatch,

    isLiveWatchConnected,
    pauseConnectLiveWatch,
    recoverConnectLiveWatch,

    watchPageChatConnected,
    setupWatchCoreConnect,
  };
});
